强网杯 thinkshopping

这题是比赛时没做出来,最后时间稍微有点没来及,没细看起了memcached的服务。memcached的crlf注入是个老问题了,今年研究生的国赛也考到了,可以参考https://www.blackhat.com/docs/us-14/materials/us-14-Novikov-The-New-Page-Of-Injections-Book-Memcached-Injections-WP.pdf

题目附件是给了docker

这题主要的难点是在于一开始如何登录进入后台,因为题目中的数据库为空,所以是查询不到数据的

image-20231227135022754

进容器应该要ps -aux或者netstat -ano看下端口和进程信息

image-20231227135300892

可以发现是启动了memcached。

再去看网站的源码,cache是采用了memcached。

image-20231227140246820

在find函数这会对cache进行查询

image-20231227140726308

再跟进去查看,其实就是调用了config里的memcached的缓存方法,其中使用的memcached类的get方法是存在crlf注入问题的。这里先说下memcached的一些语法。取值采用get key,其中key的长度不能超过250,设置值用set key flag expire_time length 再crlf换行后给出value,其中key是键名,flag的长度是32位,用于客户端标识存储的数据类型。expire_time是用来设置的过期时间,单位为秒,如果大于30天,则会被当成时间戳对待,length则是后续设置的value的长度,大小为64位。这边我们看下php的memcached的拓展对于flag的处理

image-20231227194340046

当flag的值为MEMC_VAL_IS_SERIALIZED(4),MEMC_VAL_IS_IGBINARY(5),MEMC_VAL_IS_JSON(6),MEMC_VAL_IS_MSGPACK(7)时会进行反序列化的操作。这样就可以通过此处的反序列化来触发thinkphp的反序列化链了。但是这里会遇到一个问题就是该题目可控的注入是memcached的get方法。虽然在memcached拓展的源码中并没有发现有对key长度的校验,但是在libmemcached的源码中是有对250的长度进行校验的。所以直接采用set的方式是没法触发的,这里需要采用append命令进行拼接(append命令格式与set相同),从而将反序列化链的poc写入memcached,再访问进行触发。

下面给出反序列化链的poc:

用于进行注入的python脚本

最后再带着之前设置反序列化的用户名去访问触发反序列化

image-20231227195240691

成功触发

image-20231227195254565